package com.exception;


import com.common.VoResponse;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.UnexpectedTypeException;
import java.util.List;

/**
 * @date
 * @remark 异常Advice 全局异常处理
 */
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(UnexpectedTypeException.class)
    public VoResponse unexpected(UnexpectedTypeException ex) {
        ex.printStackTrace();
        return fail("非预期的类型。");
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public VoResponse notreadavble(HttpMessageNotReadableException ex) {
        ex.printStackTrace();
        return fail("无法处理的请求。");
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public VoResponse notsupport(HttpRequestMethodNotSupportedException ex) {
        //ex.printStackTrace();
        return fail("不支持的请求方式。");
    }

    @ExceptionHandler(BindException.class)
    public VoResponse ex(BindException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        return fail("参数校验失败：" + getError(bindingResult));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public VoResponse invalid(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        return fail("非法参数：" + getError(bindingResult));
    }

    /**
     * 获取错误信息
     *
     * @param result 错误list
     * @return error
     */
    private String getError(BindingResult result) {
        List<FieldError> list = result.getFieldErrors();
        for (FieldError error : list) {
            return error.getField() + error.getDefaultMessage();
        }
        return null;
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public VoResponse illegal(IllegalArgumentException ex) {
        ex.printStackTrace();
        return fail(ex.getMessage());
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public VoResponse missing(MissingServletRequestParameterException ex) {
        ex.printStackTrace();
        return fail(ex.getMessage());
    }

    @ExceptionHandler(RuntimeException.class)
    public VoResponse runtime(RuntimeException ex) {
        ex.printStackTrace();
        return fail("处理异常。");
    }

    @ExceptionHandler(BusinessException.class)
    public VoResponse busex(BusinessException ex) {
        //ex.printStackTrace();
        return fail(ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public VoResponse error(Exception ex) {
        ex.printStackTrace();
        return fail(ex.getMessage());
    }

    private VoResponse fail(String msg) {
        VoResponse voResponse = new VoResponse();
        voResponse.setSuccess(false);
        voResponse.setInfo(msg);
        return voResponse;
    }

    //错误页面跳转 前后端分离可以不用
//    @Bean
//    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
////        return (factory->{
////            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.do");
////            factory.addErrorPages( error404Page);
////        });
//        WebServerFactoryCustomizer<ConfigurableWebServerFactory>  result = new WebServerFactoryCustomizer<ConfigurableWebServerFactory>() {
//            @Override
//            public void customize(ConfigurableWebServerFactory factory) {
//                ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.do");
//                factory.addErrorPages( error404Page);
//            }
//        };
//        //jdk 1.8 lambda
//        return  result;
//    }

}
